package demo;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class RecognitionTool {

    private int sensorTolerance;
    private int packageTolerance;

    public RecognitionTool(int sensorTolerance, int packageTolerance) {
        this.sensorTolerance = sensorTolerance;
        this.packageTolerance = packageTolerance;
    }

    /**
     * recognize方法处理了传感器异常、异物异常和商品识别的逻辑。
     * @param openLayers
     * @param closeLayers
     * @param goodsList
     * @param stockList
     * @return RecognitionResult对象
     */
    public RecognitionResult recognize(List<Layer> openLayers, List<Layer> closeLayers, List<Goods> goodsList, List<Stock> stockList) {
        List<RecognitionItem> recognizedItems = new ArrayList<>();
        List<RecognitionException> exceptions = new ArrayList<>();

        for (int i = 0; i < openLayers.size(); i++) {
            Layer openLayer = openLayers.get(i);
            Layer closeLayer = closeLayers.get(i);

            // 检查传感器异常并应用传感器容差
            int adjustedOpenWeight = applySensorTolerance(openLayer.getWeight());
            int adjustedCloseWeight = applySensorTolerance(closeLayer.getWeight());

            // 处理传感器异常
            if (openLayer.getWeight() < 0 || openLayer.getWeight() > 32767 || closeLayer.getWeight() < 0 || closeLayer.getWeight() > 32767) {
                exceptions.add(new RecognitionException(i + 1, ExceptionEnum.SENSOR_EXCEPTION, openLayer.getWeight(), closeLayer.getWeight()));
                continue;
            }

            // 处理异物异常
            if (closeLayer.getWeight() > openLayer.getWeight()) {
                exceptions.add(new RecognitionException(i + 1, ExceptionEnum.FOREIGN_OBJECT_EXCEPTION, openLayer.getWeight(), closeLayer.getWeight()));
                continue;
            }

            List<Stock> matchingStocks = findMatchingStocks(i, closeLayer.getWeight(), goodsList, stockList);

            if (matchingStocks.isEmpty()) {
                exceptions.add(new RecognitionException(i + 1, ExceptionEnum.UNRECOGNIZABLE_EXCEPTION, openLayer.getWeight(), closeLayer.getWeight()));
                continue;
            }

            for (Stock stock : matchingStocks) {
                recognizedItems.add(new RecognitionItem(stock.getGoodsId(), 1));
            }

            // 进行商品识别
            List<RecognitionItem> items = identifyItems(adjustedOpenWeight, adjustedCloseWeight, goodsList, stockList);
            recognizedItems.addAll(items);
        }
        // 处理重复商品项
        recognizedItems = removeDuplicateItems(recognizedItems);

        return new RecognitionResult(true, recognizedItems, exceptions);
    }


    /**
     * findMatchingStocks根据消费者拿取商品数量偏少的情况，只选择了最小重量差的商品作为识别结果
     * @param layerIndex
     * @param closeWeight
     * @param goodsList
     * @param stockList
     * @return List<Stock>
     */
    private List<Stock> findMatchingStocks(int layerIndex, int closeWeight, List<Goods> goodsList, List<Stock> stockList) {
        List<Stock> matchingStocks = new ArrayList<>();
        //记录每种商品的重量差
        Map<String, Integer> goodsToWeightDiffMap = new HashMap<>();

        for (Stock stock : stockList) {
            if (stock.getLayer() == layerIndex + 1) {
                for (Goods goods : goodsList) {
                    int weightDiff = Math.abs(closeWeight - goods.getWeight());
                    goodsToWeightDiffMap.put(goods.getId(), weightDiff);
                }
            }
        }

        int minWeightDiff = Integer.MAX_VALUE;
        for (int diff : goodsToWeightDiffMap.values()) {
            minWeightDiff = Math.min(minWeightDiff, diff);
        }

        // 根据最小重量差选择对应的商品
        for (Map.Entry<String, Integer> entry : goodsToWeightDiffMap.entrySet()) {
            if (entry.getValue() == minWeightDiff) {
                for (Stock stock : stockList) {
                    if (stock.getGoodsId().equals(entry.getKey()) && stock.getLayer() == layerIndex + 1) {
                        matchingStocks.add(stock);
                    }
                }
            }
        }

        return matchingStocks;
    }

    private int applySensorTolerance(int weight) {
        return weight + (int) (Math.random() * (2 * sensorTolerance + 1) - sensorTolerance);
    }

    /**
     * identifyItems方法根据重量计算购买商品清单
     * @param openWeight
     * @param closeWeight
     * @param goodsList
     * @param stockList
     * @return
     */
    private List<RecognitionItem> identifyItems(int openWeight, int closeWeight, List<Goods> goodsList, List<Stock> stockList) {
        // 实现商品识别逻辑
        // 包括根据重量计算出购买商品清单
        return new ArrayList<>();
    }

    /**
     * removeDuplicateItems方法用于移除重复的购买项
     * @param items
     * @return
     */
    private List<RecognitionItem> removeDuplicateItems(List<RecognitionItem> items) {
        // 移除重复的商品项
        // 只保留每个商品的一个购买项
        // 可以根据商品ID进行判断和去重
        return new ArrayList<>();
    }
}
